﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using Microsoft.Office.Core;
using Microsoft.Office.Tools.Ribbon;

using SharpSvn;

using OfficeSVN;


namespace PowerPointSVN {

	public partial class SvnRibbon: OfficeRibbon {

        #region Constructor
        public SvnRibbon() {
			InitializeComponent();
        }
        #endregion

        private string CurrentDoc {
            get { return Globals.ThisAddIn.Application.ActivePresentation.FullName; }
        }

		private void SvnRibbon_Load(object sender, RibbonUIEventArgs e) {
			Globals.ThisAddIn.Application.WindowActivate += new Microsoft.Office.Interop.PowerPoint.EApplication_WindowActivateEventHandler(Application_WindowActivate);
            Globals.ThisAddIn.Application.PresentationSave += new Microsoft.Office.Interop.PowerPoint.EApplication_PresentationSaveEventHandler(Application_PresentationSave);
		}

        #region Events

        void Application_PresentationSave(Microsoft.Office.Interop.PowerPoint.Presentation Pres) {
            UpdateRibbon(this.CurrentDoc);
        }

		void Application_WindowActivate(Microsoft.Office.Interop.PowerPoint.Presentation Pres, Microsoft.Office.Interop.PowerPoint.DocumentWindow Wn) {
            UpdateRibbon(this.CurrentDoc);
        }

        #endregion

        #region Button click events

        private void getLockButton_Click(object sender, RibbonControlEventArgs e) {

            SubversionHelper.GetLock(this.CurrentDoc);

            // reload the document so that word knows about the changed readonly flag
            Globals.ThisAddIn.Application.ActivePresentation.ReloadAs(MsoEncoding.msoEncodingAutoDetect);

        }

        private void releaseLockButton_Click(object sender, RibbonControlEventArgs e) {

            SubversionHelper.ReleaseLock(this.CurrentDoc);

            // reload the document so that word knows about the changed readonly flag
            Globals.ThisAddIn.Application.ActivePresentation.ReloadAs(MsoEncoding.msoEncodingAutoDetect);
        }

        private void commitButton_Click(object sender, RibbonControlEventArgs e) {

            // Ask to save the changes (if there are some unsaved changes)
            if (Globals.ThisAddIn.Application.ActivePresentation.Saved==MsoTriState.msoFalse) {
                switch (MessageBox.Show("There are unsafed changes. Do you want to save your changes?", "OfficeSVN", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question)) {
                    case DialogResult.Yes:
                        Globals.ThisAddIn.Application.ActivePresentation.Save();
                        break;
                    case DialogResult.No:
                        break;
                    case DialogResult.Cancel:
                        return;
                }
            }

            if (this.commentEditBox.Text.Length == 0) {
                MessageBox.Show("Don´t forget the comment!", "OfficeSVN");
                return;
            }

            Object Missing = System.Reflection.Missing.Value;
            string CurrentDoc = this.CurrentDoc;

            Globals.ThisAddIn.Application.ActivePresentation.Close();

            SubversionHelper.Commit((string)CurrentDoc, this.commentEditBox.Text);

            Globals.ThisAddIn.Application.Presentations.Open(CurrentDoc, MsoTriState.msoFalse, MsoTriState.msoFalse, MsoTriState.msoTrue);
        }

        private void updateButton_Click(object sender, RibbonControlEventArgs e) {

            // Idea: Check if a newer version exists. In case the working copy is up2date, than we don´t need the update...

            Object Missing = System.Reflection.Missing.Value;
            string CurrentDoc = this.CurrentDoc;

            Globals.ThisAddIn.Application.ActivePresentation.Close();

            SubversionHelper.Update((string)CurrentDoc);

            Globals.ThisAddIn.Application.Presentations.Open(CurrentDoc, MsoTriState.msoFalse, MsoTriState.msoFalse, MsoTriState.msoTrue);
            // Is it possible to activate the "OfficeSVN" ribbon again?
        }

        private void revertButton_Click(object sender, RibbonControlEventArgs e) {

            if (SubversionHelper.GetSubversionStatus(this.CurrentDoc) == SvnStatus.Added) {
                // The file is just added, so there is no write-lock

                // Remove the local file status
                SubversionHelper.Revert((string)CurrentDoc);

                // Update the ribbon
                UpdateRibbon((string)CurrentDoc);

            } else {

                // The file is already part of the repository.
                Object Missing = System.Reflection.Missing.Value;
                string CurrentDoc = this.CurrentDoc;

                // Close and re-open the document.
                Globals.ThisAddIn.Application.ActivePresentation.Close();

                SubversionHelper.Revert(CurrentDoc);

                Globals.ThisAddIn.Application.Presentations.Open(CurrentDoc, MsoTriState.msoFalse, MsoTriState.msoFalse, MsoTriState.msoTrue);
            }
        }

        private void addButton_Click(object sender, RibbonControlEventArgs e) {

            SubversionHelper.AddToSubversion(this.CurrentDoc);

            UpdateRibbon(this.CurrentDoc);
        }

        #endregion

        /// <summary>
        /// Updates the enabled status of the commands on the OfficeSVN ribbon.
        /// </summary>
        /// <remarks>
        /// This method has to be called after
        ///     - opening a document 
        ///     - saving a document
        ///     - switching between the documents 
        /// </remarks>
        /// <param name="path"></param>
        private void UpdateRibbon(string path) {

            // First, deactivate all controls
            this.addButton.Enabled = false;
            this.updateButton.Enabled = false;
            this.getLockButton.Enabled = false;
            this.releaseLockButton.Enabled = false;
            this.revertButton.Enabled = false;
            this.commitButton.Enabled = false;
            this.commentEditBox.Enabled = false;

            // Reset the information labels
            this.repositoryPathLabel.Label = "";
            this.revisionLabel.Label = "";
            this.statusLabel.Label = "Not versioned";


            SvnRibbonInfo Info = SubversionHelper.GetInfo(path);

            if (Info.RepositoryPath != null)
                this.repositoryPathLabel.Label = Info.RepositoryPath.ToString();
            this.revisionLabel.Label = Info.Revision.ToString();
            this.statusLabel.Label = Info.Status.ToString();

            switch (Info.Status) {
                case SvnStatus.Zero:
                    this.statusLabel.Label = ""; // Looks better then "Zero"
                    break;

                case SvnStatus.NotVersioned:
                    this.addButton.Enabled = true;
                    break;

                case SvnStatus.Modified:
                    this.updateButton.Enabled = true;
                    this.commitButton.Enabled = true;
                    this.commentEditBox.Enabled = true;
                    this.revertButton.Enabled = true;
                    this.releaseLockButton.Enabled = Info.IsLocked;
                    break;

                case SvnStatus.Added:
                    this.commitButton.Enabled = true;
                    this.commentEditBox.Enabled = true;
                    this.revertButton.Enabled = true; // Better: UndoAddButton?
                    break;

                case SvnStatus.None:
                case SvnStatus.Normal:
                    this.updateButton.Enabled = true;
                    this.releaseLockButton.Enabled = Info.IsLocked;
                    this.getLockButton.Enabled = (Info.NeedsLock && !Info.IsLocked);
                    break;
            }
        }
    }
}
